home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / lfslib / segUsage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-17  |  9.8 KB  |  371 lines

  1. /* 
  2.  * segUsage.c --
  3.  *
  4.  *    Routines for accessing LFS file systems seg usage table data
  5.  *    structure from a user level program
  6.  *
  7.  * Copyright 1990 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.3 90/01/12 12:03:36 douglis Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include "lfslib.h"
  22. #include "lfslibInt.h"
  23. #ifdef _HAS_PROTOTYPES
  24. #include <varargs.h>
  25. #include <sys/types.h>
  26. #endif /* _HAS_PROTOTYPES */
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <sys/file.h>
  30. #include <unistd.h>
  31. #include <bstring.h>
  32. #include <time.h>
  33.  
  34.  
  35. /*
  36.  *----------------------------------------------------------------------
  37.  *
  38.  * LfsLoadUsageArray --
  39.  *
  40.  *    Load the segment usage array into memory.
  41.  *
  42.  * Results:
  43.  *    TRUE if array can not be loaded. FALSE otherwise.
  44.  *
  45.  * Side effects:
  46.  *    None.
  47.  *
  48.  *----------------------------------------------------------------------
  49.  */
  50.  
  51. Boolean
  52. LfsLoadUsageArray(lfsPtr, checkPointSize, checkPointPtr)
  53.     Lfs    *lfsPtr;        /* File system. */
  54.     int    checkPointSize; /* Size of the checkpoint region. */
  55.     char *checkPointPtr; /* The checkpoint region. */
  56. {
  57.     LfsSegUsageCheckPoint    *cp;
  58.     LfsSegUsageEntry        *entryPtr;
  59.     LfsStableMemCheckPoint *cpPtr;
  60.     LfsStableMemParams  *smemParamsPtr;
  61.     Boolean ret = FALSE;
  62.  
  63.     if (checkPointSize < sizeof(LfsSegUsageCheckPoint)) {
  64.     fprintf(stderr,"%s: Bad SegUsage checkpoint size %d\n", 
  65.             lfsPtr->deviceName, checkPointSize);
  66.     }
  67.     smemParamsPtr = &(lfsPtr->superBlock.usageArray.stableMem);
  68.  
  69.     cp = (LfsSegUsageCheckPoint *) checkPointPtr;
  70.     bcopy((char *) cp, (char *) &lfsPtr->usageArray.checkPoint, 
  71.         sizeof(LfsSegUsageCheckPoint));
  72.     cpPtr = (LfsStableMemCheckPoint *)
  73.             (checkPointPtr + sizeof(LfsSegUsageCheckPoint));
  74.  
  75.  
  76.     lfsPtr->usageArray.smemPtr =  LfsLoadStableMem(lfsPtr, smemParamsPtr, cpPtr);
  77.     entryPtr = (LfsSegUsageEntry *) LfsGetUsageArrayEntry(lfsPtr,cp->currentSegment);
  78.     entryPtr->activeBytes = cp->curSegActiveBytes;
  79.     if (entryPtr->activeBytes <= cp->dirtyActiveBytes) {
  80.     entryPtr->flags = LFS_SEG_USAGE_DIRTY;
  81.     }
  82.     /*
  83.      * Compute the starting point of the recovery log.
  84.      */
  85.     if (cp->currentBlockOffset == -1) {
  86.     lfsPtr->logEnd.segNo = cp->cleanSegList;
  87.     lfsPtr->logEnd.blockOffset = 0;
  88.     } else { 
  89.     lfsPtr->logEnd.segNo = cp->currentSegment;
  90.     lfsPtr->logEnd.blockOffset = cp->currentBlockOffset;
  91.    }
  92.    return ret;
  93. }
  94.  
  95.  
  96.  
  97. /*
  98.  *----------------------------------------------------------------------
  99.  *
  100.  * LfsSegUsageAdjustBytes --
  101.  *
  102.  *    Adjust the active bytes count of the specified segment.
  103.  *
  104.  * Results:
  105.  *    None.
  106.  *
  107.  * Side effects:
  108.  *    None.
  109.  *
  110.  *----------------------------------------------------------------------
  111.  */
  112. void
  113. LfsSegUsageAdjustBytes(lfsPtr, diskAddr, changeInBytes)
  114.     Lfs    *lfsPtr;    /* File system. */
  115.     int    diskAddr;    /* Disk of address change. */
  116.     int    changeInBytes;    /* Amount of change. */
  117. {
  118.     int segNumber;
  119.     LfsSegUsageEntry *entryPtr;
  120.     LfsSegUsageCheckPoint    *cp = &lfsPtr->usageArray.checkPoint;
  121.  
  122.     if (diskAddr == FSDM_NIL_INDEX) {
  123.     return;
  124.     }
  125.     segNumber = LfsDiskAddrToSegmentNum(lfsPtr, diskAddr);
  126.  
  127.     if (cp->currentSegment == segNumber) {
  128.     cp->curSegActiveBytes += changeInBytes;
  129.     return;
  130.     }
  131.  
  132.     entryPtr = LfsGetUsageArrayEntry(lfsPtr, segNumber);
  133.     if (entryPtr->flags & LFS_SEG_USAGE_CLEAN) {
  134.     panic("AdjustActiveBytes called on a clean segment.\n");
  135.     }
  136.  
  137.     entryPtr->activeBytes += changeInBytes;
  138.  
  139.     if (entryPtr->activeBytes < 0) {
  140.     entryPtr->activeBytes = 0;
  141.     }
  142.     if ((entryPtr->activeBytes < cp->dirtyActiveBytes) && 
  143.     !(entryPtr->flags & LFS_SEG_USAGE_DIRTY)) {
  144.     cp->numDirty++;
  145.     entryPtr->flags |= LFS_SEG_USAGE_DIRTY;
  146.     }
  147.     if ((entryPtr->activeBytes >= cp->dirtyActiveBytes) && 
  148.     (entryPtr->flags & LFS_SEG_USAGE_DIRTY)) {
  149.     cp->numDirty--;
  150.     entryPtr->flags ^= LFS_SEG_USAGE_DIRTY;
  151.     }
  152.     LfsUsageArrayEntryModified(lfsPtr, segNumber);
  153. }
  154.  
  155.  
  156. /*
  157.  *----------------------------------------------------------------------
  158.  *
  159.  * LfsUsageCheckpoint --
  160.  *
  161.  *    Routine to handle checkpointing of the descriptor map data.
  162.  *
  163.  * Results:
  164.  *    TRUE if more data needs to be written, FALSE if this module is
  165.  *    checkpointed.
  166.  *
  167.  * Side effects:
  168.  *    Many
  169.  *
  170.  *----------------------------------------------------------------------
  171.  */
  172. Boolean
  173. LfsUsageCheckpoint(segPtr, checkPointPtr, checkPointSizePtr)
  174.     LfsSeg *segPtr;        /* Segment containing data for checkpoint. */
  175.     char   *checkPointPtr;      /* Buffer to write checkpoint data. */
  176.     int       *checkPointSizePtr;  /* Bytes added to the checkpoint area.*/
  177. {
  178.     LfsSegUsageCheckPoint *cp = (LfsSegUsageCheckPoint *) checkPointPtr;
  179.     int        size;
  180.     Boolean    full;
  181.  
  182.     *cp = (segPtr->lfsPtr->usageArray.checkPoint);
  183.     size = sizeof(LfsSegUsageCheckPoint);
  184.  
  185.     full = LfsStableMemCheckpoint(segPtr, checkPointPtr + size,
  186.         checkPointSizePtr, segPtr->lfsPtr->usageArray.smemPtr);
  187.     if (!full) { 
  188.     *checkPointSizePtr = (*checkPointSizePtr) + size;
  189.     }
  190.     return full;
  191.  
  192. }
  193.  
  194. /*
  195.  *----------------------------------------------------------------------
  196.  *
  197.  * SegUsageWriteDone --
  198.  *
  199.  *    Routine to handle finishing of a checkpoint.
  200.  *
  201.  * Results:
  202.  *    None
  203.  *
  204.  * Side effects:
  205.  *    Many
  206.  *
  207.  *----------------------------------------------------------------------
  208.  */
  209.  
  210. void
  211. LfsSegUsageWriteDone(segPtr, flags)
  212.     LfsSeg *segPtr;        /* Segment containing data for checkpoint. */
  213.     int       flags;        /* Flags for checkpoint */
  214. {
  215.     LfsSegUsage          *usagePtr = &(segPtr->lfsPtr->usageArray);
  216.  
  217.     LfsStableMemWriteDone(segPtr, flags, usagePtr->smemPtr);
  218.  
  219.     return;
  220.  
  221. }
  222.  
  223.  
  224.  
  225.  
  226. /*
  227.  *----------------------------------------------------------------------
  228.  *
  229.  * LfsSegUsageCheckpointUpdate --
  230.  *
  231.  *    This routine is used to update fields of the seg usage 
  232.  *    checkpoint that change when the checkpoint itself is 
  233.  *    written to the log.
  234.  *
  235.  * Results:
  236.  *    None.
  237.  *
  238.  * Side effects:
  239.  *    None.
  240.  *
  241.  *----------------------------------------------------------------------
  242.  */
  243. void
  244. LfsSegUsageCheckpointUpdate(lfsPtr, checkPointPtr, size)
  245.     Lfs     *lfsPtr;     /* File system being checkpointed. */
  246.     char *checkPointPtr; /* Checkpoint region for SegUsage. */
  247.     int     size;         /* Size of checkpoint region. */
  248. {
  249.     LfsSegUsage          *usagePtr = &(lfsPtr->usageArray);
  250.  
  251.     if (size < sizeof(LfsSegUsageCheckPoint)) {
  252.     panic("LfsSegUsageCheckpointUpdate bad checkpoint size.\n");
  253.     }
  254.     (*(LfsSegUsageCheckPoint *) checkPointPtr) = usagePtr->checkPoint;
  255.     return;
  256. }
  257.  
  258.  
  259.  
  260. /*
  261.  *----------------------------------------------------------------------
  262.  *
  263.  * LfsGetLogTail --
  264.  *
  265.  *    Get the next available clean blocks to write the log to.
  266.  *
  267.  * Results:
  268.  *    SUCCESS if log space was retrieved. 
  269.  *
  270.  * Side effects:
  271.  *
  272.  *
  273.  *----------------------------------------------------------------------
  274.  */
  275.  
  276. ReturnStatus
  277. LfsGetLogTail(lfsPtr, cantWait, logRangePtr, startBlockPtr)
  278.     Lfs    *lfsPtr;    /* File system of interest. */
  279.     Boolean    cantWait;      /* TRUE if we can't wait for a clean seg. */
  280.     LfsSegLogRange *logRangePtr;  /* Segments numbers returned. */
  281.     int           *startBlockPtr; /* OUT: Starting offset into segment. */
  282. {
  283.     LfsSegUsage *usagePtr = &(lfsPtr->usageArray);
  284.     LfsSegUsageCheckPoint *cp = &(usagePtr->checkPoint);
  285.     LfsSegUsageEntry *s;
  286.     int        segNumber;
  287.  
  288.  
  289.     if (!cantWait && (cp->numClean <=
  290.         lfsPtr->superBlock.usageArray.minNumClean)) {
  291.     return FS_WOULD_BLOCK;
  292.     }
  293.     if (cp->currentBlockOffset != -1) {
  294.     /*
  295.      * There is still room in the existing segment. Use it.
  296.      */
  297.     logRangePtr->prevSeg = cp->previousSegment;
  298.     logRangePtr->current = cp->currentSegment;
  299.     logRangePtr->nextSeg =  cp->cleanSegList;
  300.     (*startBlockPtr) = cp->currentBlockOffset;
  301.     return SUCCESS;
  302.     }
  303.     /*
  304.      * Need to location a new segment.
  305.      */
  306.     if (cp->numClean == 0) {
  307.     return FS_NO_DISK_SPACE;
  308.     }
  309.     /*
  310.      * Update the active bytes of the current segment the usage array.
  311.      */
  312.     s = LfsGetUsageArrayEntry(lfsPtr, cp->currentSegment);
  313.     s->activeBytes = cp->curSegActiveBytes;
  314.     if (s->activeBytes <= cp->dirtyActiveBytes) {
  315.         s->flags |= LFS_SEG_USAGE_DIRTY;
  316.         cp->numDirty++;
  317.     }
  318.     s->timeOfLastWrite = time(0);
  319.     LfsUsageArrayEntryModified(lfsPtr, cp->currentSegment);
  320.  
  321.     segNumber = cp->cleanSegList;
  322.     s = LfsGetUsageArrayEntry(lfsPtr, cp->cleanSegList);
  323.     cp->cleanSegList = s->activeBytes;
  324.  
  325.     logRangePtr->prevSeg = cp->previousSegment = cp->currentSegment;
  326.     logRangePtr->current = cp->currentSegment = segNumber;
  327.     logRangePtr->nextSeg =  cp->cleanSegList;
  328.  
  329.     cp->numClean--;
  330.     s->activeBytes = cp->curSegActiveBytes = 0;
  331.     s->flags  &= ~LFS_SEG_USAGE_CLEAN;
  332.     LfsUsageArrayEntryModified(lfsPtr, segNumber);
  333.     (*startBlockPtr) = 0;
  334.     return SUCCESS;
  335. }
  336.  
  337. /*
  338.  *----------------------------------------------------------------------
  339.  *
  340.  * LfsSetLogTail --
  341.  *
  342.  *    Set the next available clean blocks to write the log to.
  343.  *
  344.  * Results:
  345.  *    None
  346.  *
  347.  * Side effects:
  348.  *
  349.  *
  350.  *----------------------------------------------------------------------
  351.  */
  352.  
  353. void
  354. LfsSetLogTail(lfsPtr, logRangePtr, startBlock, activeBytes)
  355.     Lfs    *lfsPtr;    /* File system of interest. */
  356.     LfsSegLogRange *logRangePtr;  /* Segments numbers returned. */
  357.     int    startBlock; /* Starting offset into segment. */
  358.     int    activeBytes;    /* Number of bytes written. */
  359. {
  360.     LfsSegUsage *usagePtr = &(lfsPtr->usageArray);
  361.     LfsSegUsageCheckPoint *cp = &(usagePtr->checkPoint);
  362.  
  363.     cp->currentBlockOffset = startBlock;
  364.     if (activeBytes > 0) {
  365.     LfsSegUsageAdjustBytes(lfsPtr, 
  366.         LfsSegNumToDiskAddress(lfsPtr,logRangePtr->current)+1,
  367.         activeBytes);
  368.    }
  369. }
  370.  
  371.